跳到主要内容

03. JSON Schema

生成 JSON Schema

有两种方法生成 JSON Schema

import json
from enum import Enum

from typing import Annotated

from pydantic import BaseModel, Field
from pydantic.config import ConfigDict


class FooBar(BaseModel):
count: int
size: float | None = None


class Gender(str, Enum):
male = 'male'
female = 'female'
other = 'other'
not_given = 'not_given'


class MainModel(BaseModel):
"""
This is the description of the main model
"""

model_config = ConfigDict(title='Main')

foo_bar: FooBar
gender: Annotated[Gender | None, Field(alias='Gender')] = None
snap: int = Field(
42,
title='The Snap',
description='this is the value of snap',
gt=30,
lt=50,
)


main_model_schema = MainModel.model_json_schema() # (1)!
print(json.dumps(main_model_schema, indent=2)) # (2)!

JSON output:

  1. This produces a "jsonable" dict of MainModel's schema.
  2. Calling json.dumps on the schema dict produces a JSON string.
{
"$defs": {
"FooBar": {
"properties": {
"count": {
"title": "Count",
"type": "integer"
},
"size": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"title": "Size"
}
},
"required": [
"count"
],
"title": "FooBar",
"type": "object"
},
"Gender": {
"enum": [
"male",
"female",
"other",
"not_given"
],
"title": "Gender",
"type": "string"
}
},
"description": "This is the description of the main model",
"properties": {
"foo_bar": {
"$ref": "#/$defs/FooBar"
},
"Gender": {
"anyOf": [
{
"$ref": "#/$defs/Gender"
},
{
"type": "null"
}
],
"default": null
},
"snap": {
"default": 42,
"description": "this is the value of snap",
"exclusiveMaximum": 50,
"exclusiveMinimum": 30,
"title": "The Snap",
"type": "integer"
}
},
"required": [
"foo_bar"
],
"title": "Main",
"type": "object"
}

注意,model_json_schemamodel_dump_json 是两种东西,后者返回一个 json 字符串,用于序列化模型;前者 returns a jsonable dict representing the JSON schema of the model

Regarding the "jsonable" nature of the model_json_schema results, calling json.dumps(m.model_json_schema())on some BaseModel m returns a valid JSON string.

The TypeAdapter class lets you create an object with methods for validating, serializing, and producing JSON schemas for arbitrary types.

from typing import List

from pydantic import TypeAdapter

adapter = TypeAdapter(List[int])
print(adapter.json_schema())
#> {'items': {'type': 'integer'}, 'type': 'array'}

You can also generate JSON schemas for combinations of BaseModels and TypeAdapters, as shown in this example:

import json
from typing import Union

from pydantic import BaseModel, TypeAdapter


class Cat(BaseModel):
name: str
color: str


class Dog(BaseModel):
name: str
breed: str


ta = TypeAdapter(Union[Cat, Dog])
ta_schema = ta.json_schema()
print(json.dumps(ta_schema, indent=2))

JSON output:

{
"$defs": {
"Cat": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"color": {
"title": "Color",
"type": "string"
}
},
"required": [
"name",
"color"
],
"title": "Cat",
"type": "object"
},
"Dog": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"breed": {
"title": "Breed",
"type": "string"
}
},
"required": [
"name",
"breed"
],
"title": "Dog",
"type": "object"
}
},
"anyOf": [
{
"$ref": "#/$defs/Cat"
},
{
"$ref": "#/$defs/Dog"
}
]
}

TBD